package platform

import (
	"encoding/json"
	"net/http"
	"strconv"

	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/errors"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/hlPay"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/photonpay"
	photonmodels "gitee.com/wangshh_123/cross-pay-go/src/platform/providers/photonpay/models"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/photonpay/services"
	"gitee.com/wangshh_123/cross-pay-go/src/service"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/auth"
	commonUtils "gitee.com/wangshh_123/cross-pay-go/src/utils/common"
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// UnifiedAccountController 统一账户控制器
type UnifiedAccountController struct {
	photonPayClient            *photonpay.PhotonPayClient
	hlPayClient                *hlPay.HlPayClient
	hlPayAccountBalanceService *service.HlPayAccountBalanceService
	db                         *gorm.DB
}

// NewUnifiedAccountController 创建统一账户控制器
func NewUnifiedAccountController(photonPayClient *photonpay.PhotonPayClient, hlPayClient *hlPay.HlPayClient) *UnifiedAccountController {
	return &UnifiedAccountController{
		photonPayClient:            photonPayClient,
		hlPayClient:                hlPayClient,
		hlPayAccountBalanceService: service.NewHlPayAccountBalanceService(),
		db:                         database.DB,
	}
}

// getUserRoleAndBalance 获取用户角色和余额信息
func (c *UnifiedAccountController) getUserRoleAndBalance(ctx *gin.Context) (*UserRoleBalance, error) {
	claims, exists := ctx.Get("claims")
	if !exists {
		return nil, errors.NewAppError(http.StatusUnauthorized, "unauthorized", nil)
	}
	authClaims, ok := claims.(*auth.Claims)
	if !ok {
		return nil, errors.NewAppError(http.StatusInternalServerError, "invalid_token_claims", nil)
	}

	userID := authClaims.UserID
	roleID := authClaims.RoleID
	var balance decimal.Decimal

	// 根据角色获取相应的余额
	switch roleID {
	case 2: // 普通用户 - 返回0余额
		balance = decimal.Zero
	case 3: // 主账号 - 从主账号表获取余额
		var masterAccount models.MasterAccount
		if err := c.db.Where("user_id = ?", userID).First(&masterAccount).Error; err != nil {
			// 如果查询失败，返回0余额
			balance = decimal.Zero
		} else {
			balance = masterAccount.Balance
		}
	case 5: // 子账号 - 从子账号表获取余额
		var subAccount models.SubAccount
		if err := c.db.Where("user_id = ?", userID).First(&subAccount).Error; err != nil {
			// 如果查询失败，返回0余额
			balance = decimal.Zero
		} else {
			balance = subAccount.Balance
		}
	default:
		balance = decimal.Zero
	}

	return &UserRoleBalance{
		RoleID:  roleID,
		UserID:  userID,
		Balance: balance,
	}, nil
}

// getMatrixAccountFromToken 从token中获取matrixAccount信息
func (c *UnifiedAccountController) getMatrixAccountFromToken(ctx *gin.Context) (*models.MatrixAccountInfo, error) {
	matrixAccountInfo, exists := ctx.Get("matrix_account_info")
	if !exists {
		return nil, errors.NewAppError(http.StatusUnauthorized, "matrix_account_info_not_found", nil)
	}

	matrixAccount, ok := matrixAccountInfo.(*models.UserMatrixAccount)
	if !ok {
		return nil, errors.NewAppError(http.StatusInternalServerError, "invalid_matrix_account_info", nil)
	}

	return &models.MatrixAccountInfo{
		UserID:            matrixAccount.UserID,
		MatrixAccount:     matrixAccount.MatrixAccount,
		MatrixAccountName: matrixAccount.MatrixAccountName,
	}, nil
}

// getEffectiveMatrixAccount 获取有效的matrixAccount（子账号时获取主账号的matrixAccount）
func (c *UnifiedAccountController) getEffectiveMatrixAccount(ctx *gin.Context, userInfo *UserRoleBalance) (*models.MatrixAccountInfo, error) {
	// 获取当前用户的matrixAccount信息
	matrixAccountInfo, err := c.getMatrixAccountFromToken(ctx)
	if err != nil {
		return nil, err
	}

	// 如果用户是子账号（roleId = 5），需要获取对应的主账号的matrixAccount
	if userInfo.RoleID == 5 {
		// 查询子账号信息
		var subAccount models.SubAccount
		if err := c.db.Where("user_id = ?", userInfo.UserID).First(&subAccount).Error; err != nil {
			return nil, errors.NewAppError(http.StatusInternalServerError, "sub_account_not_found", err)
		}

		// 查询主账号信息
		var masterAccount models.MasterAccount
		if err := c.db.Where("id = ?", subAccount.MasterAccountID).First(&masterAccount).Error; err != nil {
			return nil, errors.NewAppError(http.StatusInternalServerError, "master_account_not_found", err)
		}

		// 查询主账号对应的matrixAccount
		var masterMatrixAccount models.UserMatrixAccount
		if err := c.db.Where("user_id = ?", masterAccount.UserID).First(&masterMatrixAccount).Error; err != nil {
			return nil, errors.NewAppError(http.StatusInternalServerError, "master_matrix_account_not_found", err)
		}

		// 返回主账号的matrixAccount信息
		return &models.MatrixAccountInfo{
			UserID:            masterMatrixAccount.UserID,
			MatrixAccount:     masterMatrixAccount.MatrixAccount,
			MatrixAccountName: masterMatrixAccount.MatrixAccountName,
		}, nil
	}

	// 对于其他角色，直接返回当前用户的matrixAccount
	return matrixAccountInfo, nil
}

// GetAccountList 统一获取账户列表接口
func (c *UnifiedAccountController) GetAccountList(ctx *gin.Context) {
	// 获取用户角色和余额信息
	userInfo, err := c.getUserRoleAndBalance(ctx)
	if err != nil {
		// 安全的错误类型断言
		if appErr, ok := err.(*errors.AppError); ok {
			commonUtils.Error(ctx, appErr.Code, appErr.Error(), nil)
		} else {
			commonUtils.Error(ctx, http.StatusInternalServerError, "get_user_info_failed", err)
		}
		return
	}

	// 获取有效的矩阵账户信息（子账号时获取主账号的matrixAccount）
	matrixAccountInfo, err := c.getEffectiveMatrixAccount(ctx, userInfo)
	if err != nil {
		// 安全的错误类型断言
		if appErr, ok := err.(*errors.AppError); ok {
			commonUtils.Error(ctx, appErr.Code, appErr.Error(), nil)
		} else {
			commonUtils.Error(ctx, http.StatusInternalServerError, "get_matrix_account_failed", err)
		}
		return
	}

	// 从数据库获取矩阵账户的完整信息，包括平台类型
	var userMatrixAccount models.UserMatrixAccount
	if err := c.db.Where("matrix_account = ?", matrixAccountInfo.MatrixAccount).First(&userMatrixAccount).Error; err != nil {
		commonUtils.Error(ctx, http.StatusInternalServerError, "get_matrix_account_failed", err)
		return
	}

	// 根据矩阵账户的平台类型选择不同的实现
	var result interface{}
	var err2 error

	switch userMatrixAccount.PlatformType {
	case "photonpay":
		// 使用 PhotonPay 实现
		result, err2 = c.getPhotonPayAccountList(ctx, matrixAccountInfo)
	case "hlpay":
		// 使用 HlPay 实现
		result, err2 = c.getHlPayAccountList(ctx, matrixAccountInfo)
	default:
		// 默认使用 PhotonPay
		result, err2 = c.getPhotonPayAccountList(ctx, matrixAccountInfo)
	}

	if err2 != nil {
		commonUtils.Error(ctx, http.StatusInternalServerError, "get_account_list_failed", err2)
		return
	}

	// 结构体转 map，合并本地字段
	var respMap map[string]interface{}
	b, err := json.Marshal(result)
	if err != nil {
		commonUtils.Error(ctx, http.StatusInternalServerError, "serialize_response_failed", err)
		return
	}

	if err := json.Unmarshal(b, &respMap); err != nil {
		commonUtils.Error(ctx, http.StatusInternalServerError, "deserialize_response_failed", err)
		return
	}

	respMap["roleId"] = userInfo.RoleID

	// 使用已查询的 userMatrixAccount 数据，避免重复查询
	respMap["totalTransferAmount"] = commonUtils.FormatDecimal(userMatrixAccount.TotalTransferAmount)

	// 根据角色设置本地余额
	respMap["localBalance"] = commonUtils.FormatDecimal(userInfo.Balance)

	// 根据角色和平台类型处理余额显示
	if userInfo.RoleID == 3 {
		// 对于主账号，显示主账号余额
		if data, ok := respMap["data"].([]interface{}); ok {
			for i, account := range data {
				if accountMap, ok := account.(map[string]interface{}); ok {
					if currency, ok := accountMap["currency"].(string); ok && currency == "USD" {
						// 保存原始的realTimeBalance
						accountMap["originalRealTimeBalance"] = accountMap["realTimeBalance"]

						// 使用主账号余额
						accountMap["realTimeBalance"] = commonUtils.FormatDecimal(userInfo.Balance)
						accountMap["balanceSource"] = "local"

						// 更新回数组
						data[i] = accountMap
					}
				}
			}
			respMap["data"] = data
		}
	} else if userInfo.RoleID == 5 {
		// 对于子账号，显示子账号余额
		if data, ok := respMap["data"].([]interface{}); ok {
			for i, account := range data {
				if accountMap, ok := account.(map[string]interface{}); ok {
					if currency, ok := accountMap["currency"].(string); ok && currency == "USD" {
						// 保存原始的realTimeBalance
						accountMap["originalRealTimeBalance"] = accountMap["realTimeBalance"]

						// 使用子账号余额
						accountMap["realTimeBalance"] = commonUtils.FormatDecimal(userInfo.Balance)
						accountMap["balanceSource"] = "local"

						// 更新回数组
						data[i] = accountMap
					}
				}
			}
			respMap["data"] = data
		}
	} else if userInfo.RoleID == 2 {
		// 对于普通用户，如果是HlPay平台，需要显示对应的HlPay账户余额
		if userMatrixAccount.PlatformType == "hlpay" {
			if data, ok := respMap["data"].([]interface{}); ok {
				for i, account := range data {
					if accountMap, ok := account.(map[string]interface{}); ok {
						if currency, ok := accountMap["currency"].(string); ok && currency == "USD" {
							// 查找对应的HlPay账户余额
							var hlpayAccount models.HlPayAccountBalance
							if err := c.db.Where("owner_no = ?", userMatrixAccount.MatrixAccount).First(&hlpayAccount).Error; err == nil {
								accountMap["realTimeBalance"] = commonUtils.FormatDecimal(hlpayAccount.RealTimeBalance)
								accountMap["balanceSource"] = "hlpay"
							}
							// 更新回数组
							data[i] = accountMap
						}
					}
				}
				respMap["data"] = data
			}
		}
	}

	commonUtils.Success(ctx, respMap)
}

// getPhotonPayAccountList 获取 PhotonPay 账户列表
func (c *UnifiedAccountController) getPhotonPayAccountList(ctx *gin.Context, matrixAccountInfo *models.MatrixAccountInfo) (interface{}, error) {
	params := photonmodels.AccountListQueryParams{
		AccountNo:     ctx.Query("accountNo"),
		MatrixAccount: matrixAccountInfo.MatrixAccount,
	}
	if memberId := ctx.Query("memberId"); memberId != "" {
		params.MemberID = memberId
	}

	return services.GetAccountList(ctx.Request.Context(), c.photonPayClient, params)
}

// getHlPayAccountList 获取 HlPay 账户列表
func (c *UnifiedAccountController) getHlPayAccountList(ctx *gin.Context, matrixAccountInfo *models.MatrixAccountInfo) (interface{}, error) {
	// 获取分页参数并添加输入验证
	pageIndexStr := ctx.DefaultQuery("pageIndex", "1")
	pageSizeStr := ctx.DefaultQuery("pageSize", "10")

	pageIndex, err := strconv.ParseInt(pageIndexStr, 10, 64)
	if err != nil || pageIndex < 1 {
		pageIndex = 1
	}

	pageSize, err := strconv.ParseInt(pageSizeStr, 10, 64)
	if err != nil || pageSize < 1 || pageSize > 100 {
		pageSize = 10
	}

	// 调用 HlPay 服务获取账户余额列表
	return c.hlPayAccountBalanceService.GetAccountBalancesByMatrixAccount(ctx, matrixAccountInfo.MatrixAccount, pageIndex, pageSize)
}
